home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-08 | 58.7 KB | 2,379 lines |
- head 4.2;
- access;
- symbols;
- locks; strict;
- comment @ * @;
-
-
- 4.2
- date 97.04.09.01.55.32; author lcs; state Exp;
- branches;
- next 4.1;
-
- 4.1
- date 97.04.02.22.46.37; author lcs; state Exp;
- branches;
- next 1.8;
-
- 1.8
- date 97.03.27.12.11.25; author lcs; state Exp;
- branches;
- next 1.7;
-
- 1.7
- date 97.03.26.13.32.43; author lcs; state Exp;
- branches;
- next 1.6;
-
- 1.6
- date 97.02.01.14.10.08; author lcs; state Exp;
- branches;
- next 1.5;
-
- 1.5
- date 97.01.29.15.44.49; author lcs; state Exp;
- branches;
- next 1.4;
-
- 1.4
- date 97.01.24.23.20.47; author lcs; state Exp;
- branches;
- next 1.3;
-
- 1.3
- date 97.01.23.19.55.50; author lcs; state Exp;
- branches;
- next 1.2;
-
- 1.2
- date 97.01.21.23.56.21; author lcs; state Exp;
- branches;
- next 1.1;
-
- 1.1
- date 97.01.17.23.34.28; author lcs; state Exp;
- branches;
- next ;
-
-
- desc
- @Handler for /dev/audio-like device using AHI
- @
-
-
- 4.2
- log
- @Much improved error handling.
- @
- text
- @/* $Id: main.c,v 4.1 1997/04/02 22:46:37 lcs Exp lcs $
- * $Log: main.c,v $
- * Revision 4.1 1997/04/02 22:46:37 lcs
- * Bumped to version 4
- *
- * Revision 1.8 1997/03/27 12:11:25 lcs
- * Never mind! Bah.
- *
- * Revision 1.7 1997/03/26 13:32:43 lcs
- * Added UNIT to the template, and set taskpri to 5.
- *
- * Revision 1.6 1997/02/01 14:10:08 lcs
- * A couple of bugs fixed.
- *
- * Revision 1.5 1997/01/29 15:44:49 lcs
- * It's "finished"!
- *
- * Revision 1.4 1997/01/24 23:20:47 lcs
- * Writing seem to work too...
- *
- * Revision 1.3 1997/01/23 19:55:50 lcs
- * Added AIFF and AIFC saving.
- *
- * Revision 1.2 1997/01/21 23:56:21 lcs
- * Reading seem to work okay now.
- *
- * Revision 1.1 1997/01/17 23:34:28 lcs
- * Initial revision
- *
- */
-
- /*
- * This code is written using DICE, and is based on the DosHan example
- * source code that came with the compiler. Not all comments are mine,
- * by the way...
- *
- * Done by Martin Blom 1997. Public Domain.
- *
- */
-
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/filehandler.h>
- #include <dos/rdargs.h>
-
- #include <devices/ahi.h>
- #include <proto/ahi.h>
-
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/utility_protos.h>
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "main.h"
-
-
- /*
- * Prototypes
- */
-
- LONG PlayAndSwap(struct HandlerData *, LONG);
- long extended2long(extended *);
- void ulong2extended (ULONG, extended *);
- void FillAIFFheader(struct HandlerData *);
- void FillAIFCheader(struct HandlerData *);
- LONG ReadCOMMchunk(struct HandlerData *, UBYTE *, LONG);
- long AllocAudio(int);
- void FreeAudio(void);
- long ParseArgs(struct HandlerData *, char *);
- long InitHData(struct HandlerData *);
- void FreeHData(struct HandlerData *);
- void returnpacket (struct DosPacket *);
- void Initialize (void);
- void UnInitialize (void);
-
-
- /*
- * Some macros
- */
-
- #define min(a,b) ((a)<=(b)?(a):(b))
- #define DOS_TRUE -1
- #define DOS_FALSE 0
- #define BTOC(bptr) ((void *)((long)(bptr) << 2))
- #define CTOB(cptr) ((BPTR)(((long)cptr) >> 2))
-
-
- /*
- * My debug stuff....
- */
-
- #define HIT(x) {char *a=NULL; *a=x;}
- void kprintf(char *, ...);
-
-
- /*
- * Global variables
- */
-
- const static char ID[] = "$VER: AHI-Handler 4.2 (9.4.97)\r\n";
-
- struct List HanList;
- struct DeviceNode *DevNode;
- struct MsgPort *PktPort;
- int AllocCnt;
- BOOL Running;
-
- struct MsgPort *AHImp = NULL;
- struct AHIRequest *AHIio = NULL;
- BYTE AHIDevice = -1;
- struct Library *AHIBase;
-
- struct AIFCHeader AIFCHeader = {
- ID_FORM, NULL, ID_AIFC,
- ID_FVER, sizeof(FormatVersionHeader), {
- AIFCVersion1
- },
- ID_COMM, sizeof(ExtCommonChunk), {
- 0,
- 0,
- 0,
- {0},
- NO_COMPRESSION,
- sizeof("not compressed")-1,
- 'n','o','t',' ','c','o','m','p','r','e','s','s','e','d'
- },
- ID_SSND, NULL, {0,0}
- };
-
- struct AIFFHeader AIFFHeader = {
- ID_FORM, NULL, ID_AIFF,
- ID_COMM, sizeof(CommonChunk),{
- 0,
- 0,
- 0,
- {0}
- },
- ID_SSND, NULL, {0,0}
- };
-
-
- /******************************************************************************
- **** Entry ********************************************************************
- ******************************************************************************/
-
- /*
- * Note that we use the _main entry point. Also notice that we do not
- * need to open any libraries.. they are openned for us via DICE's
- * unique auto-library-open ability.
- */
-
- void _main ()
- {
- struct DosPacket *packet;
- struct Process *proc = (struct Process *) FindTask (NULL);
-
- PktPort = &proc->pr_MsgPort;
- NewList (&HanList);
- Initialize ();
-
- Running = TRUE;
- AllocCnt = 0;
-
- #ifdef DEBUG
- kprintf("Init\n");
- #endif
-
- /*
- * Main Loop
- */
-
- while(Running) {
- struct Message *msg;
-
- while ((msg = GetMsg (PktPort)) == NULL)
- Wait (1 << PktPort->mp_SigBit);
- packet = (struct DosPacket *) msg->mn_Node.ln_Name;
-
- /*
- * default return value
- */
-
- packet->dp_Res1 = DOS_TRUE;
- packet->dp_Res2 = 0;
-
- /*
- * switch on packet
- */
-
- switch (packet->dp_Type) {
-
- case ACTION_DIE: /* ??? */
- {
- break;
- }
-
- /***********************************************************************/
-
- case ACTION_FINDUPDATE: /* FileHandle,Lock,Name Bool */
- case ACTION_FINDINPUT: /* FileHandle,Lock,Name Bool */
- case ACTION_FINDOUTPUT: /* FileHandle,Lock,Name Bool */
- {
- struct FileHandle *fh = BTOC (packet->dp_Arg1);
- unsigned char *base = BTOC (packet->dp_Arg3);
- int len = *base;
- char buf[128];
- struct HandlerData *data;
- int unit = AHI_DEFAULT_UNIT;
-
- // Skip volume name and ':'
-
- while(*++base != ':')
- --len;
- ++base;
-
- {
- // Convert /'s to blanks
-
- char *p = base;
-
- while(*++p)
- if(*p == '/')
- *p = ' ';
- }
-
- if (len >= sizeof (buf))
- len = sizeof (buf) - 1;
-
- strncpy (buf, base, len - 1);
- buf[len - 1] = '\n';
- buf[len] = 0;
-
- #ifdef DEBUG
- kprintf("ACTION_FIND#?: %s\n", (char *) buf);
- #endif
-
- data = AllocVec(sizeof(struct HandlerData), MEMF_PUBLIC | MEMF_CLEAR);
- if(! data) {
- packet->dp_Res1 = DOS_FALSE;
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- break;
- }
-
- if(packet->dp_Res2 = ParseArgs(data, (char *) buf)) {
- FreeHData(data);
- packet->dp_Res1 = DOS_FALSE;
- break;
- }
-
- if(data->args.unit) {
- unit = *data->args.unit;
- }
-
- if(packet->dp_Res2 = AllocAudio(unit)) {
- FreeAudio();
- FreeHData(data);
- packet->dp_Res1 = DOS_FALSE;
- break;
- }
-
-
- fh->fh_Arg1 = (ULONG) data;
- fh->fh_Port = (struct MsgPort *) DOS_TRUE;
- break;
- }
-
- /***********************************************************************/
-
- case ACTION_READ: /* FHArg1,CPTRBuffer,Length ActLength */
- {
-
- /*
- * Reading is straightforward except for handling EOF... We
- * must guarentee a return value of 0 (no bytes left) before
- * beginning to return EOFs (-1's). If we return a negative
- * number right off programs like COPY will assume a failure
- * (if AUDIO: is the source) and delete the destination file.
- *
- * The basic idea is to feed the packets from one buffer while
- * recording asyncroniously to the other. When we have read
- * the buffer, we wait until the other is filled, and switch
- * buffer pointers.
- */
-
- struct HandlerData *data = (struct HandlerData *) packet->dp_Arg1;
- UBYTE *dest = (void *) packet->dp_Arg2;
- LONG length, filled;
-
- #ifdef DEBUG
- kprintf("ACTION_READ: 0x%08lx, %ld\n", packet->dp_Arg2, packet->dp_Arg3);
- #endif
-
- if(! data->initialized) {
- packet->dp_Res2 = InitHData(data);
- if(packet->dp_Res2) {
- packet->dp_Res1 = -1;
- break;
- }
- }
-
- length = filled = min(data->totallength, packet->dp_Arg3);
-
- if(length <= 0) {
- packet->dp_Res1 = length;
- data->totallength = -1;
- break;
- }
-
- if(data->buffer1 == NULL) {
-
- data->buffer1 = AllocVec(data->buffersize, MEMF_PUBLIC);
- data->buffer2 = AllocVec(data->buffersize, MEMF_PUBLIC);
- data->readreq = AllocVec(sizeof (struct AHIRequest), MEMF_PUBLIC);
-
- if((data->buffer1 == NULL)
- || (data->buffer2 == NULL)
- || (data->readreq == NULL)) {
- packet->dp_Res1 = -1;
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- break;
- }
-
- CopyMem(AHIio, data->readreq, sizeof (struct AHIRequest));
-
- // Fill buffer 2
- // Note that io_Offset is always 0 the first time
-
- data->readreq->ahir_Std.io_Command = CMD_READ;
- data->readreq->ahir_Std.io_Data = data->buffer2;
- data->readreq->ahir_Std.io_Length = data->buffersize;
- data->readreq->ahir_Std.io_Offset = 0;
- data->readreq->ahir_Type = data->type;
- data->readreq->ahir_Frequency = data->freq;
- data->readreq->ahir_Volume = data->vol;
- data->readreq->ahir_Position = data->pos;
- SendIO((struct IORequest *) data->readreq);
-
- // Force buffer switch filling of the other buffer
-
- data->length = data->offset = 0;
-
- // Check if we should write a header first
-
- if(data->format == AIFF) {
- if(length < sizeof(struct AIFFHeader)) {
- packet->dp_Res1 = -1;
- packet->dp_Res2 = ERROR_BAD_NUMBER;
- break;
- }
-
- FillAIFFheader(data);
-
- CopyMem(&AIFFHeader, dest, sizeof(struct AIFFHeader));
- dest += sizeof(struct AIFFHeader);
- length -= sizeof(struct AIFFHeader);
- }
-
- else if(data->format == AIFC) {
- if(length < sizeof(struct AIFCHeader)) {
- packet->dp_Res1 = -1;
- packet->dp_Res2 = ERROR_BAD_NUMBER;
- break;
- }
-
- FillAIFCheader(data);
-
- CopyMem(&AIFCHeader, dest, sizeof(struct AIFCHeader));
- dest += sizeof(struct AIFCHeader);
- length -= sizeof(struct AIFCHeader);
- }
- }
-
-
- while(length > 0) {
- LONG thislength;
-
- if(data->offset >= data->length) {
- void *temp;
-
- temp = data->buffer1;
- data->buffer1 = data->buffer2;
- data->buffer2 = temp;
-
- if(WaitIO((struct IORequest *) data->readreq)) {
- packet->dp_Res1 = -1;
- if(data->readreq->ahir_Std.io_Error == AHIE_HALFDUPLEX) {
- packet->dp_Res2 = ERROR_OBJECT_IN_USE;
- }
- else {
- packet->dp_Res2 = ERROR_READ_PROTECTED;
- }
- break;
- }
-
- data->length = data->readreq->ahir_Std.io_Actual;
- data->offset = 0;
-
- data->readreq->ahir_Std.io_Command = CMD_READ;
- data->readreq->ahir_Std.io_Data = data->buffer2;
- data->readreq->ahir_Std.io_Length = data->buffersize;
- data->readreq->ahir_Type = data->type;
- data->readreq->ahir_Frequency = data->freq;
- data->readreq->ahir_Volume = data->vol;
- data->readreq->ahir_Position = data->pos;
- SendIO((struct IORequest *) data->readreq);
- } /* if */
-
- thislength = min(data->length - data->offset, length);
- CopyMem(data->buffer1 + data->offset, dest, thislength);
- dest += thislength;
- length -= thislength;
- data->offset += thislength;
- data->totallength -= thislength;
- } /* while */
-
- if(packet->dp_Res2 == 0) {
- packet->dp_Res1 = filled;
- }
- break;
-
- } /* ACTION_READ */
-
- /***********************************************************************/
-
- case ACTION_WRITE: /* FHArg1,CPTRBuffer,Length ActLength */
- {
- struct HandlerData *data = (struct HandlerData *) packet->dp_Arg1;
- UBYTE *src = (void *) packet->dp_Arg2;
- LONG length = packet->dp_Arg3, filled;
-
- #ifdef DEBUG
- kprintf("ACTION_WRITE: 0x%08lx, %ld\n", packet->dp_Arg2, packet->dp_Arg3);
- #endif
-
- if(data->buffer1 == NULL) {
- // Check headers?
-
- switch(data->args.format) {
- case AIFF:
- if((((ULONG *) src)[0] != ID_FORM)
- || (((ULONG *) src)[2] != ID_AIFF)) {
- packet->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
- }
- break;
-
- case AIFC:
- if((((ULONG *) src)[0] != ID_FORM)
- || (((ULONG *) src)[2] != ID_AIFC)) {
- packet->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
- }
- break;
-
- case 0:
- if(((ULONG *) src)[0] == ID_FORM) {
- if(((ULONG *) src)[2] == ID_AIFF) {
- data->args.format = AIFF;
- }
- else if(((ULONG *) src)[2] == ID_AIFC) {
- data->args.format = AIFC;
- }
- }
- break;
-
- default:
- break;
- }
-
- if(packet->dp_Res2) {
- packet->dp_Res1 = -1;
- break;
- }
-
- if((data->args.format == AIFF) || (data->args.format == AIFC)) {
- LONG skiplen = 0;
-
- skiplen = ReadCOMMchunk(data, src, length);
- src += skiplen;
- length -= skiplen;
- }
-
- if(packet->dp_Res2 = InitHData(data)) {
- packet->dp_Res1 = -1;
- break;
- }
-
- data->writing = TRUE;
-
- data->buffer1 = AllocVec(data->buffersize, MEMF_PUBLIC);
- data->buffer2 = AllocVec(data->buffersize, MEMF_PUBLIC);
-
- if((data->buffer1 == NULL) || (data->buffer2 == NULL)) {
- packet->dp_Res1 = -1;
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- break;
- }
-
- data->offset = 0;
- data->length = (data->buffersize / AHI_SampleFrameSize(data->type))
- * AHI_SampleFrameSize(data->type);
-
- }
-
- length = min(data->totallength, length);
- filled = min(data->totallength, packet->dp_Arg3);
-
- while(length > 0) {
- LONG thislength;
-
- if(data->offset >= data->length) {
- packet->dp_Res2 = PlayAndSwap(data, data->length);
- if(packet->dp_Res2) {
- packet->dp_Res1 = -1;
- break;
- }
- }
-
- thislength = min(data->length - data->offset, length);
- CopyMem(src, data->buffer1 + data->offset, thislength);
- src += thislength;
- length -= thislength;
- data->offset += thislength;
- data->totallength -= thislength;
-
- } /* while */
-
- if(packet->dp_Res2 == 0) {
- packet->dp_Res1 = filled;
- }
- break;
- }
-
- /***********************************************************************/
-
- case ACTION_END: /* FHArg1 Bool:TRUE */
- {
- struct HandlerData *data = (struct HandlerData *) packet->dp_Arg1;
-
- #ifdef DEBUG
- kprintf("ACTION_END\n");
- #endif
-
- // Abort any reading requests
-
- if(data->readreq) {
- AbortIO((struct IORequest *) data->readreq);
- WaitIO((struct IORequest *) data->readreq);
- }
-
- // Finish any playing requests
-
- if(data->writing) {
- PlayAndSwap(data, data->offset);
-
- if(data->writereq1) {
- WaitIO((struct IORequest *) data->writereq1);
- }
- if(data->writereq2) {
- WaitIO((struct IORequest *) data->writereq2);
- }
- }
-
- FreeHData(data);
- FreeAudio();
-
-
- break;
- }
-
- /***********************************************************************/
-
- case ACTION_IS_FILESYSTEM:
- packet->dp_Res1 = DOS_FALSE;
- break;
-
- /***********************************************************************/
-
- default:
- packet->dp_Res1 = DOS_FALSE;
- packet->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
- break;
-
- } /* switch */
-
- if(AllocCnt == 0)
- Running = FALSE;
-
- if (packet) {
- returnpacket (packet);
- #ifdef DEBUG
- kprintf("Retured packet\n");
- #endif
- }
-
- } /* for */
-
- #ifdef DEBUG
- kprintf("Dying..!\n");
- #endif
- UnInitialize();
- _exit (0);
- }
-
-
- /******************************************************************************
- **** PlayAndSwap **************************************************************
- ******************************************************************************/
-
- /*
- * Starts to play the current buffer. Handles double buffering.
- */
-
- LONG PlayAndSwap(struct HandlerData *data, LONG length) {
- void *temp;
-
- temp = data->buffer1;
- data->buffer1 = data->buffer2;
- data->buffer2 = temp;
-
- temp = data->writereq1;
- data->writereq1 = data->writereq2;
- data->writereq2 = temp;
-
-
- if(data->writereq1 == NULL) {
- data->writereq1 = AllocVec(sizeof (struct AHIRequest), MEMF_PUBLIC);
-
- if(data->writereq1 == NULL) {
- return ERROR_NO_FREE_STORE;
- }
-
- CopyMem(AHIio, data->writereq1, sizeof (struct AHIRequest));
- }
-
- data->offset = 0;
-
- data->writereq1->ahir_Std.io_Message.mn_Node.ln_Pri = data->priority;
- data->writereq1->ahir_Std.io_Command = CMD_WRITE;
- data->writereq1->ahir_Std.io_Data = data->buffer2;
- data->writereq1->ahir_Std.io_Length = length;
- data->writereq1->ahir_Std.io_Offset = 0;
- data->writereq1->ahir_Type = data->type;
- data->writereq1->ahir_Frequency = data->freq;
- data->writereq1->ahir_Volume = data->vol;
- data->writereq1->ahir_Position = data->pos;
- data->writereq1->ahir_Link = data->writereq2;
- SendIO((struct IORequest *) data->writereq1);
-
- if(data->writereq2) {
- if(WaitIO((struct IORequest *) data->writereq2)) {
- if(data->writereq2->ahir_Std.io_Error == AHIE_HALFDUPLEX) {
- return ERROR_OBJECT_IN_USE;
- }
- else {
- return ERROR_WRITE_PROTECTED;
- }
- }
- }
-
- return 0;
- }
-
-
- /******************************************************************************
- **** extended2long ************************************************************
- ******************************************************************************/
-
- /*
- * This function translates Apples SANE Extended used in AIFF/AIFC files
- * to a LONG. Stolen from Olaf `Olsen' Barthel's AIFF datatype.
- */
-
-
- long extended2long(extended *ex)
- {
- unsigned long mantissa;
- long exponent,sign;
-
- // We only need 32 bits precision
-
- mantissa = ex->mantissa[0];
-
- // Is the mantissa positive or negative?
-
- exponent = ex->exponent;
-
- if(exponent & 0x8000)
- sign = -1;
- else
- sign = 1;
-
- // Unbias the exponent
-
- exponent = (exponent & 0x7FFF) - 0x3FFF;
-
- // If the exponent is negative, set the mantissa to zero
-
- if(exponent < 0)
- mantissa = 0;
- else
- {
- // Special meaning?
-
- exponent -= 31;
-
- // Overflow?
-
- if(exponent > 0)
- mantissa = 0x7FFFFFFF;
- else
- mantissa >>= -exponent; // Let the point float...
- }
-
- // That's all...
-
- return(sign * (long)mantissa);
- }
-
-
- /******************************************************************************
- **** ulong2extended ***********************************************************
- ******************************************************************************/
-
- /*
- * This function translates an ULONG to Apples SANE Extended
- * used in AIFF/AIFC files.
- */
-
- void ulong2extended (ULONG in, extended *ex)
- {
- ex->exponent=31+16383;
- ex->mantissa[1]=0;
- while(!(in & 0x80000000))
- {
- ex->exponent--;
- in<<=1;
- }
- ex->mantissa[0]=in;
- }
-
-
- /******************************************************************************
- **** FillAIFFheader ***********************************************************
- ******************************************************************************/
-
- void FillAIFFheader(struct HandlerData *data) {
-
- AIFFHeader.FORMsize = sizeof(AIFFHeader) + data->totallength - 8;
- AIFFHeader.COMMchunk.numChannels = data->channels;
- AIFFHeader.COMMchunk.numSampleFrames =
- data->totallength / AHI_SampleFrameSize(data->type);
- AIFFHeader.COMMchunk.sampleSize = data->bits;
- ulong2extended(data->freq, &AIFFHeader.COMMchunk.sampleRate);
- AIFFHeader.SSNDsize = sizeof(SampledSoundHeader) + data->totallength;
- }
-
-
- /******************************************************************************
- **** FillAIFCheader ***********************************************************
- ******************************************************************************/
-
- void FillAIFCheader(struct HandlerData *data) {
-
- AIFCHeader.FORMsize = sizeof(AIFCHeader) + data->totallength - 8;
- AIFCHeader.COMMchunk.numChannels = data->channels;
- AIFCHeader.COMMchunk.numSampleFrames =
- data->totallength / AHI_SampleFrameSize(data->type);
- AIFCHeader.COMMchunk.sampleSize = data->bits;
- ulong2extended(data->freq, &AIFCHeader.COMMchunk.sampleRate);
- AIFCHeader.SSNDsize = sizeof(SampledSoundHeader) + data->totallength;
- }
-
-
- /******************************************************************************
- **** ReadCOMMchunk ************************************************************
- ******************************************************************************/
-
- LONG ReadCOMMchunk(struct HandlerData *data, UBYTE *buffer, LONG length) {
- UWORD *src = (UWORD *) buffer;
- LONG len = (length >> 1) - 2;
- ExtCommonChunk *common;
-
- while(len > 0) {
- if(((ULONG *) src)[0] == ID_COMM) {
- common = (ExtCommonChunk *) (src + 4);
- data->channels = common->numChannels;
- data->bits = common->sampleSize;
- data->totallength = common->numSampleFrames * common->numChannels *
- (data->bits <= 8 ? 1 : (data->bits <= 16 ? 2 : (data->bits <= 32 ? 4 : 0)));
- data->freq = extended2long(&common->sampleRate);
-
- if(!data->args.channels)
- data->args.channels = &data->channels;
- if(!data->args.bits)
- data->args.bits = &data->bits;
- if(!data->args.length)
- data->args.length = &data->totallength;
- if(!data->args.freq)
- data->args.freq = &data->freq;
- }
- else if(((ULONG *) src)[0] == ID_SSND) {
- src += 8;
- break;
- }
- src++;
- len--;
- }
- return (LONG) src - (LONG) buffer;
- }
-
- /******************************************************************************
- **** AllocAudio ***************************************************************
- ******************************************************************************/
-
- /*
- * If the device isn't already open, open it now
- */
-
- long AllocAudio(int unit) {
- long rc = 0;
-
- if(++AllocCnt == 1) {
- if(AHImp=CreateMsgPort()) {
- if(AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) {
- AHIio->ahir_Version = 4;
- AHIDevice=OpenDevice(AHINAME,unit,(struct IORequest *)AHIio,NULL);
- }
- }
-
- if(AHIDevice) {
- rc = ERROR_OBJECT_NOT_FOUND;
- }
- else {
- AHIBase=(struct Library *)AHIio->ahir_Std.io_Device;
- }
- }
- return rc;
- }
-
-
- /******************************************************************************
- **** FreeAudio ****************************************************************
- ******************************************************************************/
-
- /*
- * If we're the last user, close the device now
- */
-
- void FreeAudio(void)
- {
- if(--AllocCnt == 0) {
- if(AHIDevice == 0)
- CloseDevice((struct IORequest *)AHIio);
- AHIDevice = -1;
- DeleteIORequest((struct IORequest *)AHIio);
- AHIio = NULL;
- DeleteMsgPort(AHImp);
- AHImp = NULL;
- }
- }
-
-
- /******************************************************************************
- **** ParseArgs ****************************************************************
- ******************************************************************************/
-
- /*
- * Fill out argument array. Returns 0 on success, else a DOS error code.
- */
-
- long ParseArgs(struct HandlerData *data, char *initstring) {
- long rc = 0;
-
- data->rdargs = (struct RDArgs *) AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
- if(data->rdargs)
- {
- data->rdargs->RDA_Source.CS_Buffer = initstring;
- data->rdargs->RDA_Source.CS_Length = strlen(initstring);
- data->rdargs->RDA_Source.CS_CurChr = 0;
- data->rdargs->RDA_Flags |= RDAF_NOPROMPT;
-
- data->rdargs2 = ReadArgs(
- "B=BITS/K/N,C=CHANNELS/K/N,F=FREQUENCY/K/N,T=TYPE/K,V=VOLUME/K/N,P=POSITION/K/N,"
- "PRI=PRIORITY/K/N,L=LENGTH/K/N,S=SECONDS/K/N,BUF=BUFFER/K/N,UNIT/K/N",
- (LONG *) &data->args, data->rdargs);
-
- if(data->rdargs2 != NULL) {
-
-
- if(! data->args.type) {
- data->args.format = 0;
- }
- else if(Stricmp("SIGNED", data->args.type) == 0) {
- data->args.format = SIGNED;
- }
- else if(Stricmp("AIFF", data->args.type) == 0) {
- data->args.format = AIFF;
- }
- else if(Stricmp("AIFC", data->args.type) == 0) {
- data->args.format = AIFC;
- }
- else {
- rc = ERROR_BAD_TEMPLATE;
- }
- }
- else
- rc = ERROR_BAD_TEMPLATE;
-
- }
- else
- rc = ERROR_NO_FREE_STORE;
-
- return rc;
- }
-
-
- /******************************************************************************
- **** InitHData ****************************************************************
- ******************************************************************************/
-
- /*
- * Initialize the HandlerData data structure, based on the args structure
- * (see ParseArgs()). Returns 0 on success, else a DOS error code.
- */
-
- #define S8bitmode 0
- #define S16bitmode 1
- #define S32bitmode 8
-
- #define Sstereoflag 2
-
- long InitHData(struct HandlerData *data) {
- ULONG bits = 8, channels = 1, freq = 8000;
- LONG volume = 100, position = 0, priority = 0,
- length = MAXINT, buffersize = 32768;
- long rc = 0;
-
- data->initialized = TRUE;
-
- // Fill in default values
-
- if(!data->args.bits)
- data->args.bits = &bits;
- if(!data->args.channels)
- data->args.channels = &channels;
- if(!data->args.freq)
- data->args.freq = &freq;
- if(!data->args.volume)
- data->args.volume = &volume;
- if(!data->args.position)
- data->args.position = &position;
- if(!data->args.priority)
- data->args.priority = &priority;
- if(!data->args.length)
- data->args.length = &length;
- if(!data->args.buffersize)
- data->args.buffersize = &buffersize;
-
- if(!data->args.format)
- data->args.format = SIGNED;
-
- // 8, 16 or 32 bit
-
- if(*data->args.bits <= 8)
- data->type = S8bitmode;
- else if(*data->args.bits <= 16)
- data->type = S16bitmode;
- else if(*data->args.bits <= 32)
- data->type = S32bitmode;
- else {
- rc = ERROR_OBJECT_WRONG_TYPE;
- goto quit;
- }
-
- // Mono or stereo
-
- if((*data->args.channels > 2) || (*data->args.channels < 1)) {
- rc = ERROR_OBJECT_WRONG_TYPE;
- goto quit;
- }
-
- if(*data->args.channels == 2)
- data->type |= Sstereoflag;
-
- data->bits = *data->args.bits;
- data->channels = *data->args.channels;
- data->freq = *data->args.freq;
- data->vol = *data->args.volume * 0x10000 / 100;
- { // Don't ask why... :(
- LONG a;
- a = *data->args.position * 0x8000;
- a = a / 100 + 0x8000;
- data->pos = a;
- }
- data->priority = *data->args.priority;
-
- if(data->args.seconds) {
- data->totallength = *data->args.seconds * data->freq
- * AHI_SampleFrameSize(data->type);
- }
- else {
- data->totallength = (*data->args.length / AHI_SampleFrameSize(data->type))
- * AHI_SampleFrameSize(data->type);
- }
-
- data->format = data->args.format;
-
- switch(data->format) {
- case AIFF:
- case AIFC:
- data->totallength = data->totallength & ~1; // Make even
- break;
- }
-
- data->buffersize = *data->args.buffersize;
-
- quit:
- return rc;
- }
-
-
-
-
-
-
-
-
-
-
-
- /******************************************************************************
- **** FreeHData ****************************************************************
- ******************************************************************************/
-
- /*
- * Deallocate the HandlerData structure
- */
-
- void FreeHData(struct HandlerData *data) {
- if(data) {
- if(data->rdargs2)
- FreeArgs(data->rdargs2);
- if(data->rdargs);
- FreeDosObject(DOS_RDARGS, data->rdargs);
-
- FreeVec(data->buffer1);
- FreeVec(data->buffer2);
- FreeVec(data->readreq);
- FreeVec(data->writereq1);
- FreeVec(data->writereq2);
- FreeVec(data);
- }
- }
-
-
- /******************************************************************************
- **** returnpacket *************************************************************
- ******************************************************************************/
-
- /*
- * PACKET ROUTINES. Dos Packets are in a rather strange format as you
- * can see by this and how the PACKET structure is extracted in the
- * GetMsg() of the main routine.
- */
-
- void returnpacket (struct DosPacket *packet) {
- struct Message *mess;
- struct MsgPort *replyPort;
-
- replyPort = packet->dp_Port;
- mess = packet->dp_Link;
- packet->dp_Port = PktPort;
- mess->mn_Node.ln_Name = (char *) packet;
- PutMsg (replyPort, mess);
- }
-
-
- /******************************************************************************
- **** Initialize ***************************************************************
- ******************************************************************************/
-
- /*
- * During initialization DOS sends us a packet and sets our dn_SegList
- * pointer. If we set our dn_Task pointer than every Open's go to the
- * same handler (this one). If we set dn_Task to NULL, every Open()
- * will create a NEW instance of this process via the seglist, meaning
- * our process must be reentrant (i.e. -r option).
- *
- * note: dn_Task points to the MESSAGE PORT portion of the process
- * (or your own custom message port).
- *
- * If we clear the SegList then we also force DOS to reload our process
- * from disk, but we also need some way of then UnLoadSeg()ing it ourselves,
- * which we CANNOT do from this process since it rips our code out from
- * under us.
- */
-
- void Initialize () {
- struct DeviceNode *dn;
- struct Process *proc = (struct Process *) FindTask (NULL);
- struct DosPacket *packet;
-
- /*
- * Handle initial message.
- */
-
- struct Message *msg;
-
- WaitPort (PktPort);
- msg = GetMsg (PktPort);
- packet = (struct DosPacket *) msg->mn_Node.ln_Name;
-
- DevNode = dn = BTOC (packet->dp_Arg3);
- dn->dn_Task = NULL;
-
- packet->dp_Res1 = DOS_TRUE;
- packet->dp_Res2 = 0;
- returnpacket (packet);
- }
-
-
- /******************************************************************************
- **** UnInitialize *************************************************************
- ******************************************************************************/
-
- void UnInitialize (void) {
- struct DeviceNode *dn = DevNode;
-
- dn->dn_Task = NULL;
- }
- @
-
-
- 4.1
- log
- @Bumped to version 4
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.8 1997/03/27 12:11:25 lcs Exp lcs $
- d3 3
- d71 1
- a71 1
- BOOL PlayAndSwap(struct HandlerData *, LONG);
- d110 1
- a110 1
- const static char ID[] = "$VER: AHI-Handler 4.1 (2.4.97)\r\n";
- d249 1
- d256 1
- d267 1
- d306 1
- d328 1
- d357 1
- d371 1
- d394 11
- a404 1
- WaitIO((struct IORequest *) data->readreq);
- a407 6
- if(data->readreq->ahir_Std.io_Error) {
- packet->dp_Res2 = ERROR_READ_PROTECTED;
- length = 0;
- break;
- }
-
- d426 3
- a428 1
- packet->dp_Res1 = filled;
- d478 2
- a479 1
- if(packet->dp_Res2)
- d481 1
- d491 2
- a492 1
- if(packet->dp_Res2 = InitHData(data))
- d494 1
- d502 1
- d520 2
- a521 1
- if(! PlayAndSwap(data, data->length)) {
- a522 1
- length = 0;
- d536 3
- a538 1
- packet->dp_Res1 = filled;
- d588 1
- a597 2
- if (packet->dp_Res2)
- packet->dp_Res1 = DOS_FALSE;
- d622 1
- a622 1
- BOOL PlayAndSwap(struct HandlerData *data, LONG length) {
- d637 3
- a639 2
- if(data->writereq1 == NULL)
- return FALSE;
- d659 7
- a665 4
- WaitIO((struct IORequest *) data->writereq2);
-
- if(data->writereq2->ahir_Std.io_Error) {
- return FALSE;
- d669 1
- a669 1
- return TRUE;
- @
-
-
- 1.8
- log
- @Never mind! Bah.
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.7 1997/03/26 13:32:43 lcs Exp lcs $
- d3 3
- d107 1
- a107 1
- const static char ID[] = "$VER: AHI-Handler 1.8 (27.3.97)\r\n";
- d808 1
- a808 1
- AHIio->ahir_Version=3;
- @
-
-
- 1.7
- log
- @Added UNIT to the template, and set taskpri to 5.
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.6 1997/02/01 14:10:08 lcs Exp lcs $
- d3 3
- d104 1
- a104 1
- const static char ID[] = "$VER: AHI-Handler 1.7 (12.3.97)\r\n";
- a159 4
-
- /* Boost our priority */
-
- SetTaskPri(FindTask(NULL), 5);
- @
-
-
- 1.6
- log
- @A couple of bugs fixed.
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.5 1997/01/29 15:44:49 lcs Exp lcs $
- d3 3
- a29 47
- * Usage: Open AUDIO: for reading, or writing. Options can be given like
- * this: "AUDIO:PRIORITY=1 VOLUME=50". All slashes (/) in the
- * 'file' name will be translated to spaces. The removes the need
- * for quotes: AUDIO:PRIORITY/1/VOLUME/50.
- *
- *
- * The full template for reading is:
- * B=BITS/K/N,C=CHANNELS/K/N,F=FREQUENCY/K/N,T=TYPE/K,
- * L=LENGTH/K/N,S=SECONDS/K/N,BUF=BUFFER/K/N
- *
- * The full template for writing is:
- * B=BITS/K/N,C=CHANNELS/K/N,F=FREQUENCY/K/N,T=TYPE/K,
- * V=VOLUME/K/N,P=POSITION/K/N,PRI=PRIORITY/K/N,L=LENGTH/K/N,
- * S=SECONDS/K/N,BUF=BUFFER/K/N"
- *
- *
- * BITS can be one of 8, 16 or 32. CHANNELS can be either 1 or 2.
- * The FREQUENCY is in Herz, TYPE is one of SIGNED, AIFF or AIFC.
- * VOLUME ranges from 0 (silence) to 100 (full volume), and POSITION
- * ranges from -100 (far left) via 0 (center) to 100 (far right).
- * The PRIORITY is only used when writing, and can be from -128 to
- * 127 (unstoppable). LENGTH is how many bytes you wish to read or
- * write, and SECONDS is the same, but in seconds instead of bytes.
- * The BUFFER size is specified in bytes. Note that two buffers are
- * always used, which means that the memory usage will be 2×BUFFER.
- *
- *
- * The default options for reading:
- * BITS=8 CHANNELS=1 FREQUENCY=8000 TYPE=SIGNED LENGTH=very-very-much
- * BUFFER=32768.
- *
- * The default options for reading:
- * BITS=8 CHANNELS=1 FREQUENCY=8000 TYPE=<none> VOLUME=100 POSITION=0
- * PRIORITY=0 LENGTH=very-very-much BUFFER=32768.
- *
- * If TYPE is not specified, the default behavour is to identify the
- * data stream as IFF-AIFF or IFF-AIFC. If so, the default values of
- * BITS, CHANNELS, FREQUENCY and LENGTH will be changed. You can still
- * override them if you wish. If the stream could not be identified,
- * the data format is assumed to be SIGNED.
- *
- *
- * Both when reading and writing the sample rate will be converted
- * on the fly to what the underlying hardware is configured to.
- * Normally this is not a big problem when writing, but the quality
- * when reading leaves quite a lot to wish for, since no low-pass
- * filters are used.
- d68 1
- a68 1
- long AllocAudio(void);
- d101 1
- a101 1
- const static char ID[] = "$VER: AHI-Handler 1.6 (1.2.96)\r\n";
- d158 3
- d213 1
- d253 5
- a257 1
- if(packet->dp_Res2 = AllocAudio()) {
- d800 1
- a800 1
- long AllocAudio(void) {
- d807 1
- a807 1
- AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,NULL);
- d833 1
- a833 1
- if(!AHIDevice)
- d865 1
- a865 1
- "PRI=PRIORITY/K/N,L=LENGTH/K/N,S=SECONDS/K/N,BUF=BUFFER/K/N",
- @
-
-
- 1.5
- log
- @It's "finished"!
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.4 1997/01/24 23:20:47 lcs Exp lcs $
- d3 3
- d145 1
- a145 1
- const static char ID[] = "$VER: AHI-Handler 1.5 (29.1.96)\r\n";
- d423 1
- a423 1
- packet->dp_Res1 = -1;
- d805 1
- a805 2
- /*
- data->totallength = common->numSampleFrames *
- a806 1
- */
- a812 1
- /*
- a814 1
- */
- a912 3
- else if(Stricmp("UNSIGNED", data->args.type) == 0) {
- data->args.format = UNSIGNED;
- }
- a947 1
- #define Sunsignedflag 4
- d950 3
- a952 2
- ULONG bits = 8, channels = 1, freq = 8000, volume = 100, position = 0;
- LONG priority = 0, length = MAXINT, buffersize = 32768;
- d1006 6
- a1011 1
- data->pos = *data->args.position * 0x8000 / 100 + 0x8000;
- d1013 1
- a1025 3
- case UNSIGNED:
- data->type |= Sunsignedflag;
- break;
- @
-
-
- 1.4
- log
- @Writing seem to work too...
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.3 1997/01/23 19:55:50 lcs Exp lcs $
- d3 3
- d23 48
- d103 2
- d106 3
- d111 2
- a112 1
- long InitHData(struct HandlerData *, char *);
- d142 2
- d184 4
- d207 1
- d209 1
- a236 3
- kprintf("Die!\n");
- if(AllocCnt == 0)
- Running = FALSE;
- d240 2
- d275 1
- d277 12
- d292 1
- a295 1
- data = AllocVec(sizeof(struct HandlerData), MEMF_PUBLIC | MEMF_CLEAR);
- d297 2
- a298 9
- if(packet->dp_Res2 = InitHData(data, (char *) buf)) {
- FreeHData(data);
- data = NULL;
- FreeAudio();
- }
- else {
- fh->fh_Arg1 = (ULONG) data;
- fh->fh_Port = (struct MsgPort *) DOS_TRUE;
- }
- d302 2
- d324 1
- d326 8
- d383 1
- a383 8
- AIFFHeader.FORMsize = sizeof(AIFFHeader) + data->totallength - 8;
- AIFFHeader.COMMchunk.numChannels = data->channels;
- AIFFHeader.COMMchunk.numSampleFrames =
- data->totallength / AHI_SampleFrameSize(data->type);
- AIFFHeader.COMMchunk.sampleSize = data->bits;
- ulong2extended(data->freq, &AIFFHeader.COMMchunk.sampleRate);
- AIFFHeader.SSNDsize =
- sizeof(SampledSoundHeader) + data->totallength;
- d396 1
- a396 8
- AIFCHeader.FORMsize = sizeof(AIFCHeader) + data->totallength - 8;
- AIFCHeader.COMMchunk.numChannels = data->channels;
- AIFCHeader.COMMchunk.numSampleFrames =
- data->totallength / AHI_SampleFrameSize(data->type);
- AIFCHeader.COMMchunk.sampleSize = data->bits;
- ulong2extended(data->freq, &AIFCHeader.COMMchunk.sampleRate);
- AIFCHeader.SSNDsize =
- sizeof(SampledSoundHeader) + data->totallength;
- d448 2
- d454 16
- a469 1
- long length, filled;
- d471 6
- d478 25
- a502 1
- kprintf("ACTION_WRITE: 0x%08lx, %ld\n", packet->dp_Arg2, packet->dp_Arg3);
- d504 2
- a505 1
- length = filled = min(data->totallength, packet->dp_Arg3);
- d507 1
- a507 1
- if(data->buffer1 == NULL) {
- d520 1
- a520 1
- kprintf("length: %ld\n", data->length);
- d523 2
- d530 4
- a533 21
- void *temp;
-
- temp = data->buffer1;
- data->buffer1 = data->buffer2;
- data->buffer2 = temp;
-
-
- temp = data->writereq1;
- data->writereq1 = data->writereq2;
- data->writereq2 = temp;
-
-
- if(data->writereq1) {
- kprintf("Väntar på 0x%08lx..\n",data->writereq1);
- WaitIO((struct IORequest *) data->writereq1);
-
- if(data->writereq1->ahir_Std.io_Error) {
- packet->dp_Res1 = -1;
- length = 0;
- break;
- }
- d535 1
- a535 26
- else {
- data->writereq1 = AllocVec(sizeof (struct AHIRequest), MEMF_PUBLIC);
-
- if(data->writereq1 == NULL) {
- packet->dp_Res1 = -1;
- length = 0;
- break;
- }
- CopyMem(AHIio, data->writereq1, sizeof (struct AHIRequest));
- }
-
- data->offset = 0;
-
- kprintf("Spelar 0x%08lx, länkad till 0x%08lx..\n", data->writereq1, data->writereq2);
- data->writereq1->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
- data->writereq1->ahir_Std.io_Command = CMD_WRITE;
- data->writereq1->ahir_Std.io_Data = data->buffer2;
- data->writereq1->ahir_Std.io_Length = data->buffersize;
- data->writereq1->ahir_Std.io_Offset = 0;
- data->writereq1->ahir_Type = data->type;
- data->writereq1->ahir_Frequency = data->freq;
- data->writereq1->ahir_Volume = data->vol;
- data->writereq1->ahir_Position = data->pos;
- data->writereq1->ahir_Link = data->writereq2;
- SendIO((struct IORequest *) data->writereq1);
- } /* if */
- a537 1
- kprintf("Kopierar %ld bytes..\n", thislength);
- d543 1
- d550 2
- d556 1
- d558 4
- d566 12
- a577 7
- if(data->writereq1) {
- AbortIO((struct IORequest *) data->writereq1);
- WaitIO((struct IORequest *) data->writereq1);
- }
- if(data->writereq2) {
- AbortIO((struct IORequest *) data->writereq2);
- WaitIO((struct IORequest *) data->writereq2);
- a582 2
- if(AllocCnt == 0)
- Running = FALSE;
- d587 8
- a595 4
- {
- if(AllocCnt == 0)
- Running = FALSE;
- kprintf("Unknow packet!\n");
- a597 1
- }
- d601 3
- d608 3
- d615 1
- d617 1
- d623 115
- d755 78
- d859 4
- d881 4
- d886 1
- a886 1
- * Initialize the HandlerData data structure, parse the arguments
- d889 2
- a890 1
- long InitHData(struct HandlerData *data, char *initstring)
- d892 7
- a898 1
- // Returns 0 on success, else an error code
- d900 4
- a903 20
- {
- struct RDArgs *rdargs, *rdargs2;
- ULONG bits = 8, channels = 1, rate = 8000, volume = 100, position = 0;
- LONG length = MAXINT, buffersize = 32768;
- STRPTR type = "SIGNED";
- BOOL rc = 0;
-
- struct {
- ULONG *bits;
- ULONG *channels;
- ULONG *rate;
- STRPTR type;
- Fixed *volume;
- sposition *position;
- ULONG *length;
- ULONG *seconds;
- ULONG *buffersize;
- } args = {
- &bits, &channels, &rate, type, &volume, &position, &length, NULL, &buffersize
- };
- d905 1
- a905 2
- if(data == NULL)
- return ERROR_NO_FREE_STORE;
- d908 18
- a925 20
- rdargs = (struct RDArgs *) AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
- if(rdargs)
- {
- rdargs->RDA_Source.CS_Buffer = initstring;
- rdargs->RDA_Source.CS_Length = strlen(initstring);
- rdargs->RDA_Source.CS_CurChr = 0;
- rdargs->RDA_Flags |= RDAF_NOPROMPT;
-
- rdargs2 = ReadArgs(
- "B=BITS/K/N,C=CHANNELS/K/N,R=RATE/K/N,T=TYPE/K,V=VOLUME/K/N,P=POSITION/K/N,"
- "L=LENGTH/K/N,S=SECONDS/K/N,BUF=BUFFER/K/N",
- (LONG *) &args, rdargs);
-
- if(rdargs2 != NULL) {
- kprintf("%ld bits, %ld channels, %ld Hz, %s, %ld%% volume, position %ld%%, "
- "%ld bytes total, %ld seconds, %ld bytes buffer\n",
- *args.bits, *args.channels, *args.rate, args.type, *args.volume, *args.position,
- *args.length, (args.seconds ? *args.seconds : 0), *args.buffersize);
-
- FreeArgs(rdargs2);
- a929 1
- FreeDosObject(DOS_RDARGS, rdargs);
- d932 4
- a935 1
- rc = ERROR_OBJECT_WRONG_TYPE;
- d938 8
- a945 1
- if(rc == 0) {
- d954 71
- a1024 25
- // 8, 16 or 32 bit
-
- if(*args.bits <= 8)
- data->type = S8bitmode;
- else if(*args.bits <= 16)
- data->type = S16bitmode;
- else if(*args.bits <= 32)
- data->type = S32bitmode;
- else
- rc = ERROR_OBJECT_WRONG_TYPE;
-
- // Mono or stereo
-
- if(*args.channels == 2)
- data->type |= Sstereoflag;
- else if(*args.channels != 1)
- rc = ERROR_OBJECT_WRONG_TYPE;
-
- // Signed, unsigned, aiff, aifc...
-
- if(Stricmp("SIGNED", args.type) == 0) {
- data->format = RAW;
- kprintf("Signed\n");
- }
- else if(Stricmp("UNSIGNED", args.type) == 0) {
- d1026 5
- a1030 39
- data->format = RAW;
- kprintf("Unsigned\n");
- }
- else if(Stricmp("AIFF", args.type) == 0) {
- data->format = AIFF;
- kprintf("AIFF\n");
- }
- else if(Stricmp("AIFC", args.type) == 0) {
- data->format = AIFC;
- kprintf("AIFC\n");
- }
- else {
- rc = ERROR_OBJECT_WRONG_TYPE;
- }
-
- data->bits = *args.bits;
- data->channels = *args.channels;
- data->freq = *args.rate;
- data->vol = *args.volume * 0x10000 / 100;
- data->pos = *args.position * 0x8000 / 100 + 0x8000;
- if(args.seconds)
- data->totallength = *args.seconds * data->freq
- * AHI_SampleFrameSize(data->type);
- else
- data->totallength = (*args.length / AHI_SampleFrameSize(data->type))
- * AHI_SampleFrameSize(data->type);
-
- switch(data->format) {
- case AIFF:
- case AIFC:
- data->totallength = (data->totallength + 1) & ~1; // Make even
- break;
- default:
- break;
- }
-
- // User doesn't know about double buffering!
-
- data->buffersize = *args.buffersize >> 1;
- d1033 3
- d1040 13
- d1057 14
- a1070 8
- void FreeHData(struct HandlerData *data)
- {
- FreeVec(data->buffer1);
- FreeVec(data->buffer2);
- FreeVec(data->readreq);
- FreeVec(data->writereq1);
- FreeVec(data->writereq2);
- FreeVec(data);
- d1074 4
- d1084 1
- a1084 3
- void
- returnpacket (struct DosPacket *packet)
- {
- d1095 5
- a1131 3
- /*
- dn->dn_Task = PktPort;
- */
- d1139 5
- a1147 1
- /* dn->dn_SegList = NULL; */
- @
-
-
- 1.3
- log
- @Added AIFF and AIFC saving.
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.2 1997/01/21 23:56:21 lcs Exp lcs $
- d3 3
- d15 6
- a20 3
- ** This code is written using DICE, just for testing, and is based on the
- ** DosHan example source code.
- */
- d45 1
- a45 1
- #include "aifc.h"
- d48 3
- a50 6
- #define min(a,b) ((a)<=(b)?(a):(b))
- #define DOS_TRUE -1
- #define DOS_FALSE 0
- #define BTOC(bptr) ((void *)((long)(bptr) << 2))
- #define CTOB(cptr) ((BPTR)(((long)cptr) >> 2))
-
- d61 16
- a79 52
- #define RAW 0
- #define AIFF 1
- #define AIFC 2
-
- struct HandlerData {
- UBYTE *buffer1; // Address of read buffer
- UBYTE *buffer2;
- LONG length; // Offset to first invalid sample frame
- LONG offset; // Current pointer
- struct AHIRequest *req;
- UWORD bits;
- UWORD channels;
- ULONG type;
- ULONG freq;
- Fixed vol;
- sposition pos;
- LONG totallength; // Total number of bytes to play/record
- LONG buffersize; // Play/record buffer size
- UBYTE format;
- };
-
- struct AIFCHeader {
- ULONG FORMid;
- ULONG FORMsize;
- ULONG AIFCid;
-
- ULONG FVERid;
- ULONG FVERsize;
- FormatVersionHeader FVERchunk;
-
- ULONG COMMid;
- ULONG COMMsize;
- ExtCommonChunk COMMchunk;
-
- ULONG SSNDid;
- ULONG SSNDsize;
- SampledSoundHeader SSNDchunk;
- };
-
- struct AIFFHeader {
- ULONG FORMid;
- ULONG FORMsize;
- ULONG AIFFid;
-
- ULONG COMMid;
- ULONG COMMsize;
- CommonChunk COMMchunk;
-
- ULONG SSNDid;
- ULONG SSNDsize;
- SampledSoundHeader SSNDchunk;
- };
- d81 3
- d124 1
- d266 1
- d268 4
- a271 2
- if((data->buffer1 == NULL) || (data->buffer2 == NULL)) {
- packet->dp_Res1 = -1;
- d275 2
- d280 9
- a288 9
- data->req->ahir_Std.io_Command = CMD_READ;
- data->req->ahir_Std.io_Data = data->buffer2;
- data->req->ahir_Std.io_Length = data->buffersize;
- data->req->ahir_Std.io_Offset = 0;
- data->req->ahir_Type = data->type;
- data->req->ahir_Frequency = data->freq;
- data->req->ahir_Volume = data->vol;
- data->req->ahir_Position = data->pos;
- SendIO((struct IORequest *) data->req);
- d348 2
- a349 2
- WaitIO((struct IORequest *) data->req);
- data->length = data->req->ahir_Std.io_Actual;
- d352 1
- a352 1
- if(data->req->ahir_Std.io_Error) {
- d358 8
- a365 8
- data->req->ahir_Std.io_Command = CMD_READ;
- data->req->ahir_Std.io_Data = data->buffer2;
- data->req->ahir_Std.io_Length = data->buffersize;
- data->req->ahir_Type = data->type;
- data->req->ahir_Frequency = data->freq;
- data->req->ahir_Volume = data->vol;
- data->req->ahir_Position = data->pos;
- SendIO((struct IORequest *) data->req);
- d384 7
- a390 1
- long bytes = packet->dp_Arg3;
- d392 4
- a395 1
- packet->dp_Res1 = -1;
- d397 1
- a397 12
- kprintf("ACTION_WRITE: 0x%08lx, %ld\n", packet->dp_Arg2, bytes);
- #if 0
- if (xn = AllocMem (sizeof (XNode), MEMF_PUBLIC | MEMF_CLEAR)) {
- if (xn->xn_Buf = AllocMem (bytes, MEMF_PUBLIC)) {
- movmem ((char *) packet->dp_Arg2, xn->xn_Buf, bytes);
- xn->xn_Length = bytes;
- packet->dp_Res1 = bytes;
- AddTail (&xh->xh_List, &xn->xn_Node);
- xh->xh_Flags &= ~XHF_EOF;
- }
- else {
- FreeMem (xn, sizeof (XNode));
- d399 1
- d401 5
- d407 65
- a471 4
- else {
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- }
- #endif
- d480 12
- a491 2
- AbortIO((struct IORequest *) data->req);
- WaitIO((struct IORequest *) data->req);
- d504 3
- d522 1
- a522 1
- UnInitialize ();
- d634 5
- a638 4
- kprintf("%ld bits, %ld channels, %ld Hz, %s, %ld%% volume, position %ld%%, "
- "%ld bytes total, %ld seconds, %ld bytes buffer\n",
- *args.bits, *args.channels, *args.rate, args.type, *args.volume, *args.position,
- *args.length, (args.seconds ? *args.seconds : 0), *args.buffersize);
- d640 1
- a640 2
- if(data->req = AllocVec(sizeof (struct AHIRequest), MEMF_PUBLIC) ) {
- CopyMem(AHIio, data->req, sizeof (struct AHIRequest));
- d643 1
- a643 1
- rc = ERROR_NO_FREE_STORE;
- a644 1
- FreeArgs(rdargs2);
- d650 3
- d660 65
- a724 36
- // 8, 16 or 32 bit
-
- if(*args.bits <= 8)
- data->type = S8bitmode;
- else if(*args.bits <= 16)
- data->type = S16bitmode;
- else if(*args.bits <= 32)
- data->type = S32bitmode;
- else
- rc = ERROR_OBJECT_WRONG_TYPE;
-
- // Mono or stereo
-
- if(*args.channels == 2)
- data->type |= Sstereoflag;
- else if(*args.channels != 1)
- rc = ERROR_OBJECT_WRONG_TYPE;
-
- // Signed, unsigned, aiff, aifc...
-
- if(Stricmp("SIGNED", args.type) == 0) {
- data->format = RAW;
- kprintf("Signed\n");
- }
- else if(Stricmp("UNSIGNED", args.type) == 0) {
- data->type |= Sunsignedflag;
- data->format = RAW;
- kprintf("Unsigned\n");
- }
- else if(Stricmp("AIFF", args.type) == 0) {
- data->format = AIFF;
- kprintf("AIFF\n");
- }
- else if(Stricmp("AIFC", args.type) == 0) {
- data->format = AIFC;
- kprintf("AIFC\n");
- a725 26
- else {
- rc = ERROR_OBJECT_WRONG_TYPE;
- }
-
- data->bits = *args.bits;
- data->channels = *args.channels;
- data->freq = *args.rate;
- data->vol = *args.volume * 0x10000 / 100;
- data->pos = *args.position * 0x8000 / 100 + 0x8000;
- if(args.seconds)
- data->totallength = *args.seconds * data->freq
- * AHI_SampleFrameSize(data->type);
- else
- data->totallength = (*args.length / AHI_SampleFrameSize(data->type))
- * AHI_SampleFrameSize(data->type);
-
- switch(data->format) {
- case AIFF:
- case AIFC:
- data->totallength = (data->totallength + 1) & ~1; // Make even
- break;
- default:
- break;
- }
-
- // User doesn't know about double buffering!
- a726 1
- data->buffersize = *args.buffersize >> 1;
- d739 3
- a741 1
- FreeVec(data->req);
- @
-
-
- 1.2
- log
- @Reading seem to work okay now.
- @
- text
- @d1 1
- a1 1
- /* $Id: main.c,v 1.1 1997/01/17 23:34:28 lcs Exp lcs $
- d3 3
- a15 1
- #define min(a,b) ((a)<=(b)?(a):(b))
- a33 1
-
- d39 4
- d45 12
- d61 3
- a63 3
- #define BTOC(bptr) ((void *)((long)(bptr) << 2))
- #define CTOB(cptr) ((BPTR)(((long)cptr) >> 2))
-
- d71 2
- d79 1
- d82 31
- a112 4
- long AllocAudio(void);
- void FreeAudio(void);
- long InitHData(struct HandlerData *, char *);
- void FreeHData(struct HandlerData *);
- a113 3
- void returnpacket (struct DosPacket *);
- void Initialize (void);
- void UnInitialize (void);
- d124 29
- d218 1
- d221 4
- a224 1
- base++;
- a225 1
- { // Convert /'s to blanks
- d227 1
- a245 1
-
- d273 1
- a273 1
- * the buffer, we wait until the other is filed, and switch
- d292 1
- d303 1
- d315 1
- d317 42
- d444 4
- d474 17
- d508 3
- d605 1
- d616 1
- d622 7
- a628 2
- // Signed or unsigned
- if(Stricmp("UNSIGNED", args.type) == 0)
- d630 12
- a641 1
- else if(Stricmp("SIGNED", args.type) != 0)
- a642 10
-
- data->freq = *args.rate;
- data->vol = *args.volume * 0x10000 / 100;
- data->pos = *args.position * 0x8000 / 100 + 0x8000;
-
- if(data->vol > 0x10000) {
- data->vol = 0x10000;
- }
- if(data->pos > 0x10000) {
- data->pos = 0x10000;
- d645 5
- d651 2
- a652 1
- data->totallength = *args.seconds * data->freq;
- d654 11
- a664 1
- data->totallength = *args.length;
- d667 1
- d737 1
- d739 2
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d1 5
- a5 2
- /* $Id$
- * $Log$
- d8 7
- d22 4
- d29 3
- a31 1
- #include <lists.h>
- d41 3
- a46 25
- typedef struct DosPacket DosPacket;
- typedef struct FileHandle FileHandle;
- typedef struct DeviceNode DeviceNode;
- typedef struct Process Process;
- typedef struct Node Node;
- typedef struct List List;
- typedef struct MsgPort MsgPort;
- typedef struct Message Message;
-
- typedef struct XHandle {
- Node xh_Node;
- long xh_XHLen;
- long xh_Refs;
- long xh_Flags;
- List xh_List;
- } XHandle;
-
- #define XHF_EOF 0x0001
-
- typedef struct XNode {
- Node xn_Node;
- char *xn_Buf;
- long xn_Offset;
- long xn_Length;
- } XNode;
- d48 20
- a67 1
- void returnpacket (DosPacket *);
- d71 9
- a79 4
-
- List HanList;
- DeviceNode *DevNode;
- MsgPort *PktPort;
- d89 5
- a93 5
- DosPacket *packet;
- {
- Process *proc = (struct Process *) FindTask (NULL);
- PktPort = &proc->pr_MsgPort;
- }
- d97 5
- d106 21
- a126 2
- for (;;)
- {
- d128 30
- a157 1
- Message *msg;
- d159 24
- a182 3
- while ((msg = GetMsg (PktPort)) == NULL)
- Wait (1 << PktPort->mp_SigBit);
- packet = (DosPacket *) msg->mn_Node.ln_Name;
- d185 27
- a211 14
- /*
- * default return value
- */
-
- packet->dp_Res1 = DOS_TRUE;
- packet->dp_Res2 = 0;
-
- /*
- * switch on packet
- */
-
- switch (packet->dp_Type)
- {
- case ACTION_DIE: /* ??? */
- d213 46
- a258 28
- case ACTION_FINDUPDATE: /* FileHandle,Lock,Name Bool */
- case ACTION_FINDINPUT: /* FileHandle,Lock,Name Bool */
- case ACTION_FINDOUTPUT: /* FileHandle,Lock,Name Bool */
- {
- FileHandle *fh = BTOC (packet->dp_Arg1);
- XHandle *xh;
-
- {
- unsigned char *base = BTOC (packet->dp_Arg3);
- int len = *base;
- char buf[128];
-
- if (len >= sizeof (buf))
- len = sizeof (buf) - 1;
-
- strncpy (buf, base + 1, len);
- buf[len] = 0;
-
- if ((xh = (XHandle *) FindName (&HanList, buf)) == NULL)
- {
- xh = AllocMem (sizeof (XHandle) + len + 1, MEMF_PUBLIC | MEMF_CLEAR);
- xh->xh_XHLen = sizeof (XHandle) + len + 1;
- xh->xh_Node.ln_Name = (char *) (xh + 1);
- movmem (buf, xh->xh_Node.ln_Name, len + 1);
- NewList (&xh->xh_List);
- AddTail (&HanList, &xh->xh_Node);
- }
- ++xh->xh_Refs;
- a259 54
- fh->fh_Arg1 = (ULONG) xh;
- fh->fh_Port = (MsgPort *) DOS_TRUE;
- }
- break;
- case ACTION_READ: /* FHArg1,CPTRBuffer,Length ActLength */
- /*
- * reading is straightforward except for handling EOF ... we
- * must guarentee a return value of 0 (no bytes left) before
- * beginning to return EOFs (-1's). If we return a negative
- * number right off programs like COPY will assume a failure
- * (if TEST: is the source) and delete the destination file
- */
-
- {
- XHandle *xh = (XHandle *) packet->dp_Arg1;
- long bytes;
-
- packet->dp_Res1 = 0;
- while ((bytes = packet->dp_Arg3 - packet->dp_Res1) > 0)
- {
- XNode *xn = (XNode *) RemHead (&xh->xh_List);
-
- if (xn == NULL)
- break;
-
- if (bytes > xn->xn_Length - xn->xn_Offset)
- bytes = xn->xn_Length - xn->xn_Offset;
- movmem (xn->xn_Buf + xn->xn_Offset, (char *) packet->dp_Arg2 + packet->dp_Res1, bytes);
-
- xn->xn_Offset += bytes;
- packet->dp_Res1 += bytes;
- if (xn->xn_Offset == xn->xn_Length)
- {
- FreeMem (xn->xn_Buf, xn->xn_Length);
- FreeMem (xn, sizeof (XNode));
- }
- else
- {
- AddHead (&xh->xh_List, &xn->xn_Node);
- }
- }
- if (packet->dp_Res1 == 0 && GetHead (&xh->xh_List) == NULL)
- {
- if (xh->xh_Flags & XHF_EOF)
- packet->dp_Res1 = -1; /* EOF */
- xh->xh_Flags |= XHF_EOF;
- }
- }
- break;
- case ACTION_WRITE: /* FHArg1,CPTRBuffer,Length ActLength */
- {
- XHandle *xh = (XHandle *) packet->dp_Arg1;
- XNode *xn;
- long bytes = packet->dp_Arg3;
- d261 39
- a299 21
- packet->dp_Res1 = -1;
- if (xn = AllocMem (sizeof (XNode), MEMF_PUBLIC | MEMF_CLEAR))
- {
- if (xn->xn_Buf = AllocMem (bytes, MEMF_PUBLIC))
- {
- movmem ((char *) packet->dp_Arg2, xn->xn_Buf, bytes);
- xn->xn_Length = bytes;
- packet->dp_Res1 = bytes;
- AddTail (&xh->xh_List, &xn->xn_Node);
- xh->xh_Flags &= ~XHF_EOF;
- }
- else
- {
- FreeMem (xn, sizeof (XNode));
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- }
- }
- else
- {
- packet->dp_Res2 = ERROR_NO_FREE_STORE;
- }
- d301 3
- a303 11
- break;
- case ACTION_END: /* FHArg1 Bool:TRUE */
- {
- XHandle *xh = (XHandle *) packet->dp_Arg1;
-
- if (--xh->xh_Refs == 0 && GetHead (&xh->xh_List) == NULL)
- {
- Remove (&xh->xh_Node);
- FreeMem (xh, xh->xh_XHLen);
- }
- break;
- a304 4
- break;
- default:
- packet->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
- break;
- d306 2
- a307 5
- if (packet)
- {
- if (packet->dp_Res2)
- packet->dp_Res1 = DOS_FALSE;
- returnpacket (packet);
- d309 29
- d340 1
- a340 3
- /*
- * no reached
- */
- d342 1
- d349 168
- d523 1
- a523 2
- returnpacket (packet)
- DosPacket *packet;
- d525 2
- a526 2
- Message *mess;
- MsgPort *replyPort;
- d551 4
- a554 6
- void
- Initialize ()
- {
- DeviceNode *dn;
- Process *proc = (Process *) FindTask (NULL);
- DosPacket *packet;
- d559 2
- d562 3
- a564 7
- {
- Message *msg;
-
- WaitPort (PktPort);
- msg = GetMsg (PktPort);
- packet = (DosPacket *) msg->mn_Node.ln_Name;
- }
- d566 2
- a567 2
- {
- DevNode = dn = BTOC (packet->dp_Arg3);
- a568 2
- dn->dn_Task = PktPort;
- }
- d574 2
- a575 5
- void
- UnInitialize (void)
- {
- {
- DeviceNode *dn = DevNode;
- d577 2
- a578 3
- dn->dn_Task = NULL;
- /* dn->dn_SegList = NULL; */
- }
- @
-